cmake_minimum_required(VERSION 3.10)
project(KPBFV5.0)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# 设置构建类型为 Release
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
 # Release 编译选项 (优化级别设置为 -O3)
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
set(CMAKE_C_FLAGS_RELEASE "-O3")


# 显式设置编译器
set(CMAKE_C_COMPILER gcc)
set(CMAKE_CXX_COMPILER g++)

# 针对鲲鹏920的优化flags
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    # 基础优化
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")

    # ARM64架构特定优化
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8.2-a")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=tsv110")

    # 其他优化选项
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -funroll-loops")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fomit-frame-pointer")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftree-vectorize")

    # ARM NEON 向量化
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftree-vectorize")

    # OpenMP支持
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
endif()

# 启用链接时优化 (LTO)
include(CheckIPOSupported)
check_ipo_supported(RESULT LTO_SUPPORTED OUTPUT error)
if(LTO_SUPPORTED)
    set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
    message(STATUS "Link Time Optimization is enabled.")
endif()

# 查找并配置 GMP
find_path(GMP_INCLUDE_DIR
    NAMES gmp.h
    PATHS /opt/homebrew/include /usr/local/include /usr/include
    NO_DEFAULT_PATH
)

find_library(GMP_LIB
    NAMES gmp
    PATHS /opt/homebrew/lib /usr/local/lib /usr/lib
    NO_DEFAULT_PATH
)

find_library(GMPXX_LIB
    NAMES gmpxx
    PATHS /opt/homebrew/lib /usr/local/lib /usr/lib
    NO_DEFAULT_PATH
)

# 配置 NTL
set(NTL_INCLUDE_DIR "/usr/local/include")
set(NTL_LIB_DIR "/usr/local/lib")

include_directories(${NTL_INCLUDE_DIR})

# 添加所有库源文件
file(GLOB LIB_SOURCES "src/*.cpp")
list(FILTER LIB_SOURCES EXCLUDE REGEX "main\\.cpp$")

# 创建静态库
add_library(maintest STATIC ${LIB_SOURCES})

# 设置包含目录
target_include_directories(maintest PUBLIC
    ${GMP_INCLUDE_DIR}
)

# 链接库
target_link_libraries(maintest PRIVATE
    ${GMP_LIB}
    ${GMPXX_LIB}
)

# 设置OpenMP环境变量
set(ENV{OMP_NUM_THREADS} 32)
set(ENV{OMP_SCHEDULE} "dynamic,1")
set(ENV{OMP_PROC_BIND} "spread")
set(ENV{OMP_PLACES} "threads")

# 添加可执行文件
aux_source_directory(. SOURCES)
add_executable(BGV ${SOURCES})

# 设置编译标志
set_target_properties(BGV PROPERTIES
    COMPILE_FLAGS "${CMAKE_CXX_FLAGS}"
)

# 链接所有依赖
target_link_libraries(BGV PRIVATE
    maintest
    ${GMP_LIB}
    ${GMPXX_LIB}
    ${NTL_LIB_DIR}/libntl.a
)